package com.gitee.feizns.quickstart.mybatis.flex.handler.type;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.TypeReference;
import com.mybatisflex.annotation.Column;
import org.apache.ibatis.type.TypeHandler;

/**
 * 使用{@link JSON}转换复杂泛型JSON
 * <p>
 *     mybatis plus对实体中的字段的复杂泛型支持<br/>
 *     对于泛型中是自定义的类型时：使用通过继承该接口来实现对应属性的的类型转换支持
 * </p>
 * <p>
 *     首先自定义一个{@link TypeHandler}<br/>
 * </p>
 * <pre>{@code
 *   public class PersonListTypeHandler extends Fastjson2GenericTypeHandler<List<Person>> {}
 * }</pre>
 * <p>
 *     再配置实体类时配置{@link Column#typeHandler()}<br/>
 * </p>
 * <pre class="code">
 * &#064;TableName(autoResultMap = true)
 * public class User {
 *     &#064;TableField(typeHandler=PersonListTypeHandler.class)
 *     private List<Person> persons;
 * }
 * </pre>
 * @param <T> 元素类型
 * @see TypeReference
 * @see TypeHandler
 * @author feizns
 * @since 2023/2/27
 */
@SuppressWarnings("all")
public class Fastjson2GenericTypeHandler<T> extends TypeReference<T> implements JsonTypeHandler<T> {

    /**
     * 默认的json写入规则
     */
    private static final JSONWriter.Feature[] DEFAULT_FEATURES = {
            JSONWriter.Feature.WriteEnumsUsingName
    };

    /**
     * json写入配置
     * 默认配置写入枚举使用：用枚举name
     */
    private final JSONWriter.Feature[] features;

    public Fastjson2GenericTypeHandler() {
        features = DEFAULT_FEATURES;
    }

    public Fastjson2GenericTypeHandler(JSONWriter.Feature[] features) {
        this.features = features;
    }

    @Override
    public String toJson(Object object) {
        return JSON.toJSONString(object, features);
    }

    @Override
    public T parse(String json) {
        return JSON.parseObject(json, this);
    }

}
